﻿using System.Collections;
using System.Collections.Generic;
using SnakeGame;
using UnityEngine;
using UnityEngine.UI;

public class startGame : MonoBehaviour
{
    //游戏需要的属性
    public int Speed;
    public int Score { get; set; }
    public bool isGaming;
    private float diffTime;

    // 游戏中的主要对象
    public Snake mySnake { get; set; }
    public NodePoint food { get; set; }

    // UI中的一些组件的引用
    public Text speedText { get; set; }
    public Text scoreText { get; set; }
    public Button addBtn { get; set; }
    public GameObject startView { get; set; }
    public Button startBtn { get; set; }

    //资源
    public GameObject NodePointRes;

    // Start is called before the first frame update
    void Start()
    {
        Screen.SetResolution(1920, 1080, false);
        InitData();
        InitUI();
        ShowStartView(true);
    }

    /// <summary>
    /// 初始化数据时调用
    /// </summary>
    void InitData()
    {
        //资源读取
        NodePointRes = Resources.Load("Prefab/NodePoint") as GameObject;
        //生成一条蛇
        mySnake = new Snake(NodePointRes);
        //速度
        Speed = 3;
        //分数
        Score = 0;
        //随机生成食物
        GenerateFood();
    }

    /// <summary>
    /// 初始化UI组件的引用&按钮点击事件
    /// </summary>
    void InitUI()
    {
        speedText = GameObject.Find("UIViewGame/Bg/SpeedText").GetComponent<Text>();
        speedText.text = "Speed：" + Speed;
        scoreText = GameObject.Find("UIViewGame/Bg/ScoreText").GetComponent<Text>();
        scoreText.text = "Score：" + Score;

        addBtn = GameObject.Find("UIViewGame/Bg/AddButton").GetComponent<Button>();
        startView = GameObject.Find("UIViewGame/StartGameBg").gameObject;
        startBtn = GameObject.Find("UIViewGame/StartGameBg/StartGameBtn").GetComponent<Button>();

        addBtn.onClick.AddListener(() =>
        {
            if ((Speed + 1) <= Constant.Speed.Length)
            {
                Speed++;
            }
            else
            {
                Speed = 1;
            }

            speedText.text = "Speed：" + Speed;
        });

        startBtn.onClick.AddListener(() =>
        {
            isGaming = true;
            Score = 0;
            ShowStartView(false);
        });
    }

    // Update is called once per frame
    void Update()
    {
        if (!isGaming)
        {
            return;
        }

        diffTime += Time.deltaTime;
        if (diffTime >= Constant.Speed[Speed - 1])
        {
            mySnake.MoveForward();
            var hasEaten = mySnake.CheckEatFood(food);
            if (hasEaten)
            {
                Score += Constant.NodeScore;
                scoreText.text = "Score：" + Score;
                GenerateFood();
            }

            //是否死亡
            var isDead = mySnake.CheckIsDead();
            if (isDead)
            {
                RestartGame();
                return;
            }

            diffTime -= Constant.Speed[Speed - 1];
        }

        if (Input.GetKeyDown(KeyCode.A))
        {
            mySnake.ChangeSnakeDirection(Vector2.left);
        }

        else if (Input.GetKeyDown(KeyCode.S))
        {
            mySnake.ChangeSnakeDirection(Vector2.up);
        }

        else if (Input.GetKeyDown(KeyCode.D))
        {
            mySnake.ChangeSnakeDirection(Vector2.right);
        }

        else if (Input.GetKeyDown(KeyCode.W))
        {
            mySnake.ChangeSnakeDirection(Vector2.down);
        }
    }

    /// <summary>
    /// 随机生成食物，黑名单算法避开蛇蛇身体
    /// </summary>
    void GenerateFood()
    {
        //保存蛇身已占用索引
        Dictionary<int, int> idxDic = new Dictionary<int, int>();
        foreach (var nodePoint in mySnake.bodyList)
        {
            var idx = (nodePoint.y - 1) * Constant.MapWidth + nodePoint.x;
            idxDic.Add(idx, 1);
        }

        //挑出没有被蛇身占用的索引
        List<int> idxList = new List<int>();
        for (int i = 1; i <= Constant.MapHeight * Constant.MapWidth; i++)
        {
            if (!idxDic.ContainsKey(i))
            {
                idxList.Add(i);
            }
        }

        //随机索引
        int randomIdx = idxList[Random.Range(0, idxList.Count)];
        //生成食物
        food = new NodePoint(NodePointRes);
        //坐标计算
        int pos_x = randomIdx % Constant.MapWidth;
        if (pos_x == 0)
        {
            pos_x = Constant.MapWidth;
        }

        int pos_y = (randomIdx - 1) / Constant.MapWidth + 1;

        food.RefreshPosition(pos_x, pos_y);
    }

    /// <summary>
    /// 打开开始游戏页面
    /// </summary>
    /// <param name="isShow">是否展示页面</param>
    void ShowStartView(bool isShow)
    {
        startView.SetActive(isShow);
    }

    /// <summary>
    /// 重新开始游戏
    /// </summary>
    void RestartGame()
    {
        isGaming = false;
        mySnake.ResetSnake();
        food.OnDestroy();
        GenerateFood();
        ShowStartView(true);
    }
}